/**
 * @HttpClient.java  COPYRIGHT xiaojian
 * 
 * Created on 2017年5月25日 下午7:45:46
 */
package xj.toolkit.netty.client;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jmx.export.MBeanExporter;

import com.google.common.base.Preconditions;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpMessage;
import xj.toolkit.netty.initializer.HttpClientInitializer;
import xj.toolkit.netty.server.HttpServer;

/**
 * @author <a href="mailto:cxj2000@gmail.com">xiaojian.cao</a>
 *
 */
public class HttpClient {

	private static final Logger logger = LoggerFactory.getLogger(HttpServer.class);

	private static final int MAX_RETRY = 20;
	private static final long RETRY_TIMEOUT = 30 * 1000; // 30s

	private Bootstrap bootstrap = new Bootstrap();
	private String acceptIp = "0.0.0.0";
	private int acceptPort = 80;
	private int dumpBytes = 256;
	private HttpClientInitializer clientInitializer;

	// JMX support
	private volatile MBeanExporter mbeanExporter = null;

	/**
	 * @throws IOException
	 */
	public void start() throws Exception {
		bootstrap.group(new NioEventLoopGroup()).channel(NioSocketChannel.class).option(ChannelOption.SO_BACKLOG, 10240)
				.option(ChannelOption.SO_REUSEADDR, true).option(ChannelOption.SO_RCVBUF, 8 * 1024)
				.option(ChannelOption.SO_KEEPALIVE, false);
		bootstrap.handler(clientInitializer);
	}

	public void send(HttpMessage message) {
		Preconditions.checkArgument(message != null);
		Channel channel = this.bootstrap.bind().channel();

		if (channel == null || !channel.isActive()) {
			throw new IllegalArgumentException("Cannot get http connection.");
		}

		channel.writeAndFlush(message);
		channel.close();
	}

	public void stop() {
		// TODO
	}

	public String getAcceptIp() {
		return acceptIp;
	}

	public void setAcceptIp(String acceptIp) {
		this.acceptIp = acceptIp;
	}

	public int getAcceptPort() {
		return acceptPort;
	}

	public void setAcceptPort(int acceptPort) {
		this.acceptPort = acceptPort;
	}

	public int getDumpBytes() {
		return dumpBytes;
	}

	public void setDumpBytes(int dumpBytes) {
		this.dumpBytes = dumpBytes;
	}

	public HttpClientInitializer getClientInitializer() {
		return clientInitializer;
	}

	public void setClientInitializer(HttpClientInitializer clientInitializer) {
		this.clientInitializer = clientInitializer;
	}

	public MBeanExporter getMbeanExporter() {
		return mbeanExporter;
	}

	public void setMbeanExporter(MBeanExporter mbeanExporter) {
		this.mbeanExporter = mbeanExporter;
	}
}
